package com.lvmama.pangolin.util;

import java.util.*;

import org.ansj.domain.Result;
import org.ansj.domain.Term;
import org.ansj.splitWord.analysis.ToAnalysis;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.lvmama.pangolin.busi.config.ConfigManager;
import com.lvmama.pangolin.common.Constant;
import com.lvmama.pangolin.common.StringTools;
import com.lvmama.pangolin.entity.SegVo;
import com.lvmama.pangolin.entity.match.MatchSynonymWords;
import com.lvmama.pangolin.entity.match.MatchTicketCommodity;
import com.lvmama.pangolin.match.service.MatchSynonymWordsService;

@Component
public class CommodityMatchUtil
{
	private static Logger logger = Logger.getLogger(CommodityMatchUtil.class);
	private static final String COMBINEDCOMMODITY_PLUS= "+";//组合票常常出现的符号
	private static final String COMBINEDCOMMODITY_MUTIPLICATION= "*";//组合票常常出现的符号
	private static final String COMBINEDCOMMODITY_SLIGHT_PAUSE= "、";//组合票常常出现的符号

	@Autowired
    public MatchSynonymWordsService matchSynonymWordsService;
	
	private List<MatchSynonymWords> synonyList = null;

	/**
	 * 判断基本商品是否是组合商品
	 * @param str
	 * @return
	 */
	public boolean isCombinedCommodity(String str)
	{
		boolean ret = false ;
		if(str==null)
		{
			return false;
		}
		if(str.indexOf(COMBINEDCOMMODITY_PLUS)>0
				||str.indexOf(COMBINEDCOMMODITY_MUTIPLICATION)>0
				||str.indexOf(COMBINEDCOMMODITY_SLIGHT_PAUSE)>0)
		{
			ret = true;
		}
		return ret;
	}


    public  String maxScore(MatchTicketCommodity commodity,List<MatchTicketCommodity> commodityList)
	{
    	String lvCommodity = null;
    	try
    	{
    		String name = commodity.getCommodityName();
    		if(!StringTools.isValid(name))
    		{
    			return lvCommodity;
    		}
    		
    		if(!StringTools.isValid(commodity.getPredealName()) 
    				|| !StringTools.isValid(commodity.getSegName()))
    		{
    			preHandelMatchTicketCommodity(commodity);
    		}
    		commodityType(commodity);
    		String preName = commodity.getPredealName();
    		String segName = commodity.getSegName();
    		boolean match = false;
    		if(commodityList != null && !commodityList.isEmpty())
    		{
    			String mname = null;
    			String mpreName = null;
    			String msegName = null;
    			for (MatchTicketCommodity temp : commodityList)
    			{
    				if(!StringTools.isValid(temp.getCommodityName()))
    	    		{
    	    			continue;
    	    		}
    				if(!StringTools.isValid(temp.getPredealName()) 
    						|| !StringTools.isValid(temp.getSegName()))
    				{
    					preHandelMatchTicketCommodity(temp);
    				}
    				
    				mname = temp.getCommodityName();
    				mpreName = temp.getPredealName();
    				msegName = temp.getSegName();
    				if(name.equals(mname)||preName.equals(mpreName)
    						||segName.equals(msegName))			
    				{
    					lvCommodity = temp.getCommodityId();
    					match = true;
    					break;
    				}
    				else
    				{
    					float score = score(segName,msegName);
    					
    					float priceScore = priceScore(commodity.getPrice(),temp.getPrice());
    					float scorem = priceScore*0.2f + score*0.8f;
    					temp.setScore(scorem);
    				}
    			}
    			if(!match)
    			{
    				Collections.sort(commodityList, new Comparator<MatchTicketCommodity>()
    				{
    					public int compare(MatchTicketCommodity o1, MatchTicketCommodity o2)
    					{
    						int temp = 0;
    						if(o1.getScore() >o2.getScore())
    						{
    							temp = -1;
    						}
    						else if(o1.getScore() < o2.getScore())
    						{
    							temp = 1;
    						}
    						return temp;
    					}
    				});
    				for (MatchTicketCommodity temp : commodityList)
    				{
    					commodityType(temp);
    					if(commodity.getCommodityType().equals(temp.getCommodityType()) 
    							&& commodity.getPackageType().equals(temp.getPackageType()))
    					{
    						if(temp.getScore() > 0.5f)
    						{
								lvCommodity = temp.getCommodityId();
								break;
    						}
    					}
    					
    				}
    				
    				
    			}
    		}
    	}catch (Exception e)
    	{
    		logger.error("获取评分失败！" + commodity.toString(),e);
    	}
		
		return lvCommodity;
	}
    
    public void matchSort(MatchTicketCommodity commodity,List<MatchTicketCommodity> commodityList)
    {
    	if(commodity == null || commodityList == null || commodityList.isEmpty())
    	{
    		return;
    	}
    	String name = commodity.getCommodityName();
		if(!StringTools.isValid(commodity.getPredealName()) 
				|| !StringTools.isValid(commodity.getSegName()))
		{
			preHandelMatchTicketCommodity(commodity);
		}
		commodityType(commodity);
		String preName = commodity.getPredealName();
		String segName = commodity.getSegName();
		if(commodityList != null && !commodityList.isEmpty())
		{
			String mname = null;
			String mpreName = null;
			String msegName = null;
			for (MatchTicketCommodity temp : commodityList)
			{
				if(!StringTools.isValid(temp.getPredealName()) 
						|| !StringTools.isValid(temp.getSegName()))
				{
					preHandelMatchTicketCommodity(temp);
				}
				commodityType(temp);
				
				mname = temp.getCommodityName();
				mpreName = temp.getPredealName();
				msegName = temp.getSegName();
				if(name.equals(mname)||preName.equals(mpreName)
						||segName.equals(msegName))			
				{
					temp.setScore(1f);
				}
				else
				{
					float score = score(segName,msegName);
					float priceScore = priceScore(commodity.getPrice(),temp.getPrice());
					float typeScore = 0f;
					if(commodity.getCommodityType().equals(temp.getCommodityType()))
					{
						typeScore = 1f;
					}
					float scorem = priceScore*0.2f + score*0.6f + typeScore*0.2f;
					temp.setScore(scorem);
				}
				
			}
			
			Collections.sort(commodityList, new Comparator<MatchTicketCommodity>()
			{
				public int compare(MatchTicketCommodity o1, MatchTicketCommodity o2)
				{
					int temp = 0;
					if(o1.getScore() >o2.getScore())
					{
						temp = -1;
					}
					else if(o1.getScore() < o2.getScore())
					{
						temp = 1;
					}
					return temp;
				}
			});
		}
    }
    
    //录入数据预处理
    public void preHandelMatchTicketCommodity(MatchTicketCommodity matchTicketCommodity) 
    {
    	String realName = null;
    	try
    	{
    		//当城市缺失，用省份填充
        	if(!StringTools.isValid(matchTicketCommodity.getCityCode())){
            	matchTicketCommodity.setCityCode(matchTicketCommodity.getProvinceCode());
            }
        	//判断商品是否是组合商品，用"+"做匹配
        	//如果是组合商品，则不对商品名称做预处理
        	
        	String commodityName = matchTicketCommodity.getCommodityName();
        	if(synonyList == null)
        	{
        		if(matchSynonymWordsService == null)
        		{
        			matchSynonymWordsService = (MatchSynonymWordsService) SpringContextUtil
        					.getBean(MatchSynonymWordsService.class);
        		}
        		synonyList = matchSynonymWordsService.findAll();
        	}
        	
        	if(synonyList != null && !synonyList.isEmpty())
        	{
        		for (MatchSynonymWords matchSynonymWords : synonyList)
				{
        			if(commodityName.contains(matchSynonymWords.getSourceWord()))
        			{
        				commodityName = commodityName.replaceAll(matchSynonymWords.getSourceWord(), matchSynonymWords.getSynonymWord());
        			}
        			
				}
        	}
        	
        	if(!commodityName.contains(Constant.COMMODITY_AUTO_MATCH_PLUS_CHARACTER)
        			&& !commodityName.contains("＋"))
        	{
        		String productName = matchTicketCommodity.getProductName();
        		
        		//匹配商品名称是否包含1，产品名称 2，省份名称 3，城市名称
        		//按优先级匹配，存在即去除
        		
        		//替换无意义数据
    			commodityName = commodityName.replaceAll(productName, "");
    			commodityName = commodityName.replaceAll(matchTicketCommodity.getProvinceCode(), "");
    			commodityName = commodityName.replaceAll(matchTicketCommodity.getCityCode(), "");
    			commodityName = commodityName.replaceAll(productName, "");
    			productName = productName.replaceAll("\\(|\\)|\\[|\\]", "");
    			Result result = ToAnalysis.parse(productName);
        		if(result != null && result.getTerms() != null)
        		{
        			List<Term> termList = result.getTerms();
        			for (Term term : termList)
    				{
        				realName = term.getRealName();
        				commodityName = commodityName.replace(realName, "");
    				}
        		}
        		
    			
        	}
        	//替换无意义字符
        	ConfigManager config = ConfigManager.getInstance();

        	//A做分隔符
        	String deflaut = "\\(|\\)|（|）|，|,|、| |【|】";
        	String specialChar = config.getParamValue("MATCH_PRE_DEAL", "SPECIAL_CHAR",deflaut);
        	commodityName = commodityName.replaceAll(specialChar,"");
        	if(!StringTools.isValid(commodityName))
        	{
        		commodityName = matchTicketCommodity.getCommodityName();
        	}
        	matchTicketCommodity.setPredealName(commodityName);
    		Result result = ToAnalysis.parse(commodityName);
    		matchTicketCommodity.setSegName(result.toStringWithOutNature());
    		
    	}catch(Exception e)
    	{
    		logger.error("数据预处理失败！" +  e.getMessage() +" : " + matchTicketCommodity.toString(),e);
    	}
    	

	}
	
    public float score(String segName,String msegName)
	{
		List<SegVo> nameList = null;
		List<SegVo> mnameList = null;
		float scroe = 0f;
		int segLen = 0;
		int msegLen = 0;
		int strLen = 0;
		int mstrLen = 0;
		
		int segLen_match = 0;
		int msegLen_match = 0;
		int strLen_match = 0;
		int mstrLen_match = 0;
		
		if(StringTools.isValid(segName))
		{
			nameList = new ArrayList<SegVo>();
			String[]  name = segName.split(",");
			for (int i = 0; i < name.length; i++)
			{
				SegVo vo = new SegVo();
				vo.setSeq(i);
				vo.setName(name[i]);
				vo.setMatch(false);
				nameList.add(vo);
				strLen += name[i].length();
				segLen ++;
			}
		}
		if(StringTools.isValid(msegName))
		{
			mnameList = new ArrayList<SegVo>();
			String[]  name = msegName.split(",");
			for (int i = 0; i < name.length; i++)
			{
				SegVo vo = new SegVo();
				vo.setSeq(i);
				vo.setName(name[i]);
				vo.setMatch(false);
				mnameList.add(vo);
				mstrLen += name[i].length();
				msegLen ++;
			}
		}
		if((nameList == null || nameList.isEmpty())
				||(mnameList == null || mnameList.isEmpty()))
		{
			scroe = 0f;
		}else
		{
			for (SegVo seg : nameList)
			{
				String name = seg.getName();
				for (SegVo vo : mnameList)
				{
					if(name.equals(vo.getName()))
					{
						if(!vo.isMatch())
						{
							seg.setMatch(true);
							vo.setMatch(true);
							segLen_match ++;
							msegLen_match ++;
							strLen_match += name.length();
							mstrLen_match += name.length();
							break;
						}
						
					}
				}
			}
			scroe = ((0.5f*segLen_match)/(segLen) + (0.5f*strLen_match)/strLen)*0.6f
					+ ((0.5f*msegLen_match)/(msegLen) + (0.5f*mstrLen_match)/mstrLen)*0.4f;
		}
		return scroe;
	}
	
	public float priceScore(String basePrice,String price)
	{
		float score = 0f;
		if(StringTools.isValid(basePrice) && StringTools.isValid(price))
		{
			if(Float.valueOf(basePrice) > 0f)
			{
				Float temp = Math.abs((Float.valueOf(basePrice)-Float.valueOf(price)));
				score = 1f - temp/(Float.valueOf(basePrice)*0.1f);
				if(score > 1f || score< 0f)
				{
					score = 0f;
				}
			}
			
		}
		return score;
	}
	
	public void commodityType(MatchTicketCommodity commodity)
	{
		String  name = commodity.getPredealName();
		String type = "成人";
		if(StringTools.isValid(name))
		{
			if(name.contains("+")  || name.contains("＋"))
			{
				commodity.setPackageType("组合票");
			}
			else
			{
				commodity.setPackageType("常规票");
			}
			String defaultType = "优待,亲子,家庭,儿童,学生,老人,双人,三人";
			ConfigManager config = ConfigManager.getInstance();
			String commodityType = config.getParamValue("MATCH_PRE_DEAL", "COMMODITY_TYPE",defaultType);
			String[] strArr = commodityType.split(",");
			if(strArr != null && strArr.length > 0)
			{
				
				for (int i = 0; i < strArr.length; i++)
				{
					if(name.contains(strArr[i]))
					{
						type = strArr[i];
						break;
					}
				}
			}
				
			
		}
		commodity.setCommodityType(type);
		
	}

	/**
	 * 根据商品名称获取商品类型
	 * @param commodityName
	 * @return
	 */
	public String commodityType(String commodityName)
	{
		String  name = commodityName;
		String type = "成人";
		if(StringTools.isValid(name))
		{
			if(name.contains("+")  || name.contains("＋"))
			{
				type="组合票";
			}
			else
			{
				type="常规票";
			}
			String defaultType = "优待,亲子,家庭,儿童,学生,老人,双人,三人";
			ConfigManager config = ConfigManager.getInstance();
			String commodityType = config.getParamValue("MATCH_PRE_DEAL", "COMMODITY_TYPE",defaultType);
			String[] strArr = commodityType.split(",");
			if(strArr != null && strArr.length > 0)
			{

				for (int i = 0; i < strArr.length; i++)
				{
					if(name.contains(strArr[i]))
					{
						type = strArr[i];
						break;
					}
				}
			}

		}
		return type;
	}

	/**
	 * 对产品的名称进行预处理
	 * @param commodityName
	 * @return
	 */
	public Map<String,String> preHandelMatchTicketCommodity(String commodityName){
		Map<String,String> retMap = new HashMap<>();
		retMap.put("preName","");
		retMap.put("segName","");
		try {

				if(synonyList == null)
				{
					if(matchSynonymWordsService == null)
					{
						matchSynonymWordsService = (MatchSynonymWordsService) SpringContextUtil
								.getBean(MatchSynonymWordsService.class);
					}
					synonyList = matchSynonymWordsService.findAll();
				}

				if(synonyList != null && !synonyList.isEmpty())
				{
					for (MatchSynonymWords matchSynonymWords : synonyList)
					{
						if(commodityName.contains(matchSynonymWords.getSourceWord()))
						{
							commodityName = commodityName.replaceAll(matchSynonymWords.getSourceWord(), matchSynonymWords.getSynonymWord());
						}

					}
				}

//			if(!commodityName.contains(Constant.COMMODITY_AUTO_MATCH_PLUS_CHARACTER)
//					&& !commodityName.contains("＋"))
//			{
				//匹配商品名称是否包含1，产品名称 2，省份名称 3，城市名称
				//按优先级匹配，存在即去除
				//替换无意义数据
//				commodityName = commodityName.replaceAll(productName, "");
//				commodityName = commodityName.replaceAll(cityCode, "");
//				commodityName = commodityName.replaceAll(productName, "");
//				productName = productName.replaceAll("\\(|\\)|\\[|\\]", "");
//				Result result = ToAnalysis.parse(productName);
//				if(result != null && result.getTerms() != null)
//				{
//					List<Term> termList = result.getTerms();
//					for (Term term : termList)
//					{
//						realName = term.getRealName();
//						commodityName = commodityName.replace(realName, "");
//					}
//				}
//			}
				//替换无意义字符
				ConfigManager config = ConfigManager.getInstance();

				//A做分隔符
				String deflaut = "\\(|\\)|（|）|，|,|、| |【|】";
				String specialChar = config.getParamValue("MATCH_PRE_DEAL", "SPECIAL_CHAR",deflaut);
				commodityName = commodityName.replaceAll(specialChar,"");
				Result result = ToAnalysis.parse(commodityName);
				retMap.put("preName",commodityName);
				retMap.put("segName",result.toStringWithOutNature());


		}catch (Exception e){
			logger.error("数据预处理失败！" +  e.getMessage() +" : " ,e);
		}
		return retMap;
	}


	/**
	 * 对字符串进行预处理
	 * @param str
	 * @return
	 */
	public Map<String,String> preHandelString(String str){
		Map<String,String> retMap = new HashMap<>();
		retMap.put("preName","");
		retMap.put("segName","");
		try {

			if(synonyList == null)
			{
				if(matchSynonymWordsService == null)
				{
					matchSynonymWordsService = (MatchSynonymWordsService) SpringContextUtil
							.getBean(MatchSynonymWordsService.class);
				}
				synonyList = matchSynonymWordsService.findAll();
			}

			if(synonyList != null && !synonyList.isEmpty())
			{
				for (MatchSynonymWords matchSynonymWords : synonyList)
				{
					if(str.contains(matchSynonymWords.getSourceWord()))
					{
						str = str.replaceAll(matchSynonymWords.getSourceWord(), matchSynonymWords.getSynonymWord());
					}

				}
			}
			//替换无意义字符
			ConfigManager config = ConfigManager.getInstance();
			//A做分隔符
			String deflaut = "\\(|\\)|（|）|，|,|、| |【|】";
			String specialChar = config.getParamValue("MATCH_PRE_DEAL", "SPECIAL_CHAR",deflaut);
			str = str.replaceAll(specialChar,"");
			Result result = ToAnalysis.parse(str);
			retMap.put("preName",str);
			retMap.put("segName",result.toStringWithOutNature());
		}catch (Exception e){
			logger.error("数据预处理失败！" +  e.getMessage() +" : " ,e);
		}
		return retMap;
	}
}
